<template>
  <div style="height: 100%">
    <a-spin :spinning="isTableLoading" wrapperClassName="spinning-container">
      <div class="header-container" ref="headerContainer">
        <page-header class="header" :title="l('FileManager')"></page-header>
        <a-card :bordered="false">
          <!-- 按钮 -->
          <a-row :gutter="8">
            <a-col :sm="22" :md="20">
              <a-upload
                class="fileUpload"
                :action="uploadFileUrl"
                :multiple="false"
                v-model:file-list="uploadfileList"
                :headers="uploadHeaders"
                @change="uploadChange"
                @beforeUpload="beforupload"
              >
                <a-button type="primary" style="margin-right: 0px">
                  <upload-outlined />
                  <span>{{ l('FileUpload') }}</span>
                </a-button>
              </a-upload>
              <a-button @click="openDirectory">
                <plus-outlined />
                {{ l('CreateDirectory') }}
              </a-button>
              <a-button @click="refresh">
                <reload-outlined />
                {{ l('Refresh') }}
              </a-button>
            </a-col>
            <a-col :sm="2" :md="4" style="text-align: right">
              <a-button @click="showType = 'big'" :disabled="showType === 'big'">
                <appstore-outlined />
              </a-button>
              <a-button
                class="bars-btn"
                @click="showType = 'small'"
                :disabled="showType === 'small'"
              >
                <bars-outlined />
              </a-button>
            </a-col>
          </a-row>
          <!-- big横向展示 -->
          <section class="big-list-item" v-show="showType === 'big'">
            <a-row :gutter="10">
              <a-col :sm="3" v-if="path.length > 1" @click="back()" class="file-item">
                <rollback-outlined class="file-item__icon iconfont" style="font-size: 29px" />
                <div class="file-item__name" style="text-align: center">...</div>
                <!-- 路径比较深的显示back按钮 -->
              </a-col>

              <a-col
                :sm="3"
                v-for="item in dataList"
                :key="item?.id"
                :class="{ file_item__selected: item.selected }"
                @click="cho(item)"
                style="background-color: #d3d3d333; margin: 0px 5px"
              >
                <div class="dd-btn">
                  <a-dropdown>
                    <a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
                      <more-outlined />
                    </a>
                    <template #overlay>
                      <a-menu>
                        <a-menu-item>
                          <a-popconfirm
                            placement="top"
                            :okText="l('Ok')"
                            :cancelText="l('Cancel')"
                            @confirm="copyImg(item)"
                          >
                            <template #title>{{ l('AreYouSure') }}</template>
                            <a href="javascript:;">{{ l('Copy') }}</a>
                          </a-popconfirm>
                        </a-menu-item>
                        <a-menu-item>
                          <a
                            href="javascript:;"
                            @click="copyData(item.path, 'link', '.copylink')"
                            :data-clipboard-text="copyText"
                            class="copylink"
                            >{{ l('CopyUrl') }}</a
                          >
                        </a-menu-item>
                        <a-menu-item>
                          <a
                            href="javascript:;"
                            @click="copyData(item.path, 'code', '.copycode')"
                            :data-clipboard-text="copyText"
                            class="copycode"
                            >{{ l('CopyCode') }}</a
                          >
                        </a-menu-item>
                        <a-menu-item>
                          <a href="javascript:;" @click="rename(item)">{{ l('ReName') }}</a>
                        </a-menu-item>
                        <a-menu-item>
                          <a href="javascript:;" @click="movefile(item)">{{ l('Move') }}</a>
                        </a-menu-item>
                        <a-menu-item>
                          <!-- <a href="javascript:;">{{ l('DeleteSysFile') }}</a> -->
                          <a-popconfirm
                            placement="top"
                            :okText="l('Ok')"
                            :cancelText="l('Cancel')"
                            @confirm="remove(item.id)"
                          >
                            <template #title>{{ l('AreYouSure') }}</template>
                            <a href="javascript:;">{{ l('DeleteSysFile') }}</a>
                          </a-popconfirm>
                        </a-menu-item>
                      </a-menu>
                    </template>
                  </a-dropdown>
                </div>
                <folder-two-tone
                  v-if="item.dir === true"
                  class="file-item__icon iconfont"
                  :class="'icon-' + item.fileExt"
                  style="font-size: 29px"
                />
                <div v-if="item.dir === false">
                  <i
                    v-if="!item.isImg"
                    class="file-item__icon iconfont"
                    :class="'icon-' + item.fileExt"
                    style="font-size: 29px"
                  ></i>
                  <div
                    class="file-item__img"
                    v-if="item.isImg"
                    :style="{ 'background-image': 'url(' + item.path + ')' }"
                  >
                  </div>
                </div>
                <div class="file_item__name">{{ item.name }}</div>
                <div class="file_item__pixel">
                  <span v-if="item.isImg">{{ item.width }}x{{ item.height }}</span>
                </div>
              </a-col>
            </a-row>
            <a-pagination
              v-show="totalItems > 0"
              class="pagination"
              size="middle"
              :total="totalItems"
              showSizeChanger
              showQuickJumper
              :showTotal="showTotalInfo"
              @change="pageNumberChange"
              @showSizeChange="pageNumberChange"
              v-model:current="pageNumber"
              v-model:pageSize="pageSize"
              :pageSizeOptions="pageSizeOptions"
            />
          </section>
        </a-card>
      </div>
      <!-- smalltable展示 -->
      <div class="small-list-item table-container" v-show="showType === 'small'">
        <div v-if="path.length > 1" @click="back()" class="back-item">
          <rollback-outlined />&nbsp;&nbsp;...
        </div>
        <a-table
          size="middle"
          :scroll="{ x: tableWidthScroll, y: tableHeightScroll }"
          :rowKey="(record) => record.id"
          :columns="columns"
          :data-source="dataList"
          :pagination="{
            total: totalItems,
            current: pageNumber,
            pageSize: pageSize,
            showTotal: showTotalInfo,
            showQuickJumper: true,
            showSizeChanger: true,
            change: pageNumberChange,
            showSizeChange: pageNumberChange,
            pageSizeOptions: pageSizeOptions,
            size: 'middle',
          }"
          :customRow="tableclick"
          @change="tableChange"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'name'">
              <div class="icon-container">
                <folder-two-tone
                  v-if="record.dir === true"
                  class="file-item__icon iconfont"
                  :class="'icon-' + record.fileExt"
                  style="font-size: 29px"
                />
                <i
                  v-if="record.dir === false && !record.isImg"
                  class="file-item__icon iconfont"
                  :class="'icon-' + record.fileExt"
                  style="font-size: 29px"
                ></i>
                <div
                  class="file-item__img"
                  v-if="record.dir === false && record.isImg"
                  :style="{ 'background-image': 'url(' + record.path + ')' }"
                ></div>
              </div>
              {{ record.name }}
            </template>
            <template v-if="column.key === 'pixel'">
              <span v-if="record.isImg">{{ record.width }}x{{ record.height }}</span>
            </template>
            <template v-if="column.key === 'lastModificationTime'">
              {{ _moment(record.lastModificationTime) }}
              <div class="dd-btn">
                <a-dropdown>
                  <a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
                    <menu-outlined />
                  </a>
                  <template #overlay>
                    <a-menu>
                      <a-menu-item>
                        <a-popconfirm
                          placement="top"
                          :okText="l('Ok')"
                          :cancelText="l('Cancel')"
                          @confirm="copyImg(record)"
                        >
                          <template #title>{{ l('AreYouSure') }}</template>
                          <a href="javascript:;">{{ l('Copy') }}</a>
                        </a-popconfirm>
                      </a-menu-item>
                      <a-menu-item>
                        <a
                          href="javascript:;"
                          @click="copyData(record.path, 'link', '.copylink')"
                          :data-clipboard-text="copyText"
                          class="copylink"
                          >{{ l('CopyUrl') }}</a
                        >
                      </a-menu-item>
                      <a-menu-item>
                        <a
                          href="javascript:;"
                          @click="copyData(record.path, 'code', '.copycode')"
                          :data-clipboard-text="copyText"
                          class="copycode"
                          >{{ l('CopyCode') }}</a
                        >
                      </a-menu-item>
                      <a-menu-item>
                        <a href="javascript:;" @click="rename(record)">{{ l('ReName') }}</a>
                      </a-menu-item>
                      <a-menu-item>
                        <a href="javascript:;" @click="movefile(record)">{{ l('Move') }}</a>
                      </a-menu-item>
                      <a-menu-item>
                        <!-- <a href="javascript:;">{{ l('DeleteSysFile') }}</a> -->
                        <a-popconfirm
                          placement="top"
                          :okText="l('Ok')"
                          :cancelText="l('Cancel')"
                          @confirm="remove(record)"
                        >
                          <template #title>{{ l('AreYouSure') }}</template>
                          <a href="javascript:;">{{ l('DeleteSysFile') }}</a>
                        </a-popconfirm>
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </div>
            </template>
          </template>
        </a-table>
      </div>
    </a-spin>
  </div>
</template>

<script lang="ts">
  import { PagedListingComponentBase } from '/@/shared/component-base';
  import { SysFileEditDto, SysFileServiceProxy } from '/@/shared/service-proxies';
  import { AppConsts } from '/@/abpPro/AppConsts';
  import CreateDirectory from './create-directory.vue';
  import Rename from './rename.vue';
  import MoveFile from './move-file.vue';
  import { defineComponent } from 'vue';
  import {
    MoreOutlined,
    BarsOutlined,
    AppstoreOutlined,
    PlusOutlined,
    ReloadOutlined,
    UploadOutlined,
    RollbackOutlined,
    MenuOutlined,
    FileTwoTone,
    FolderTwoTone,
  } from '@ant-design/icons-vue';
  import Clipboard from 'clipboard';
  import { ColumnType } from 'ant-design-vue/lib/table';
  import { IPagedRequestDto } from '/@/shared/component-base/interfaces';

  export default defineComponent({
    name: 'file-manager',
    mixins: [PagedListingComponentBase],
    components: {
      CreateDirectory,
      Rename,
      MoveFile,
      MoreOutlined,
      BarsOutlined,
      AppstoreOutlined,
      PlusOutlined,
      ReloadOutlined,
      UploadOutlined,
      RollbackOutlined,
      MenuOutlined,
      FileTwoTone,
      FolderTwoTone,
    },
    data() {
      return {
        // 显示类型
        showType: 'big',
        sysFileServiceProxy: new SysFileServiceProxy(),
        parentId: '',
        dataList: new Array<any>(),
        filepath: AppConsts.remoteServiceBaseUrl + '/File/GetFile?filePath=',
        // 上传文件
        uploadfileList: new Array<any>(),
        uploadFileUrl: '',
        uploadHeaders: {},
        // 路劲深度
        path: new Array<string>(),
        copyText: '',
        maxProfilPictureBytesValue: 100, //AppConsts.maxProfilPictureMb,
      };
    },
    created() {
      this.sysFileServiceProxy = new SysFileServiceProxy(this.$apiUrl, this.$api);
      Object.assign(this.uploadHeaders, {
        Authorization: 'Bearer ' + abp.auth.getToken(),
      });
      this.getFileUploadUrl('');
      // if (this.parentId) {
      this.path.push(this.parentId);
      // }
    },
    methods: {
      // 获取列
      getColumns(): ColumnType<SysFileEditDto>[] {
        return [
          {
            title: 'No',
            customRender: ({ index }) => {
              const a = (this.pageNumber - 1) * this.pageSize + (index + 1);
              return a;
            },
            width: 60,
            fixed: 'left',
          },
          {
            title: this.l('FileName'),
            dataIndex: 'name',
            key: 'name',
            ellipsis: true,
          },
          {
            title: this.l('Pixel'),
            dataIndex: 'pixel',
            key: 'pixel',
            ellipsis: true,
          },
          {
            title: this.l('LastModificationTime'),
            dataIndex: 'lastModificationTime',
            key: 'lastModificationTime',
            ellipsis: true,
          },
        ];
      },
      /**
       * 获取数据
       */
      fetchDataList(request: IPagedRequestDto, finishedCallback?: () => void) {
        this.sysFileServiceProxy
          .getPaged(this.parentId, '', '', request.maxResultCount, request.skipCount)
          .finally(() => {
            finishedCallback!();
          })
          .then((res) => {
            this.dataList = res.items?.map((item: any) => {
              item.fileExt = item.fileExt?.replace('.', '');
              item.selected = false;
              item.path = this.filepath + item.path;
              item.lastModificationTime =
                item.lastModificationTime != undefined
                  ? item.lastModificationTime
                  : item.creationTime;
              return item;
            }) as Array<any>;
            this.showPaging(res);
          });
      },
      /**
       * 获取上传文件地址
       */
      getFileUploadUrl(parendId: string) {
        this.uploadFileUrl =
          AppConsts.remoteServiceBaseUrl + '/api/services/app/SysFile/Create?parentId=' + parendId;
      },

      /**
       * big
       * 点击item
       */
      cho(item: any) {
        if (!item.dir) {
          return;
        }
        if (item.id) {
          this.next(item);
          return;
        }
      },
      /**
       * 进入文件夹
       */
      next(i: { id: string | number }) {
        this.path.push(i.id.toString());
        this.parentId = i.id.toString();
        this.getFileUploadUrl(i.id.toString());
        this.refreshGoFirstPage();
      },
      /**
       *上传文件
       */
      uploadChange(info: { file: any; fileList: any }): void {
        if (info.file.status === 'error') {
          this.notify.error(this.l('FileSavedFailed'));
          return;
        }
        if (info.file.status === 'done') {
          this.notify.success(this.l('SavedSuccessfully'));
          this.isTableLoading = false;
          let fileList = [...info?.fileList];
          fileList = fileList.slice(-2);
          fileList = fileList.map((file) => {
            if (file.response) {
              file.url = file.response.url;
            }
            return file;
          });
          this.uploadfileList = fileList;
          this.refresh();
          return;
        }
      },
      /**
       * 新建文件夹
       */
      openDirectory() {
        this.modalHelper
          .create(
            CreateDirectory,
            {
              parentId: this.parentId,
            },
            {
              width: '400px',
            },
          )
          .subscribe((res) => {
            if (res) {
              this.refresh();
            }
          });
      },
      /**
       * 返回上一级
       */
      back() {
        this.path.pop(); // 移除最后一个元素
        const length = this.path.length;
        const tempParentId = this.path[length - 1];
        if (!tempParentId) {
          this.parentId = '';
        } else {
          this.parentId = tempParentId;
        }
        this.getFileUploadUrl(this.parentId);
        this.refresh();
      },
      /**
       * 单机table
       */
      tableclick(record: any, _index: any) {
        return {
          onClick: () => {
            this.cho(record);
          },
        };
      },
      /**
       * 复制文件
       * @param id 待copy文件id
       */
      copyImg(item: any) {
        if (item.dir) {
          this.notify.warn(this.l('FolderCannotBeCopied'));
          return;
        }
        this.isTableLoading = true;
        let sysFiledto: SysFileEditDto = new SysFileEditDto();
        sysFiledto.init(item);
        this.sysFileServiceProxy
          .copyFile(sysFiledto)
          .finally(() => {
            this.isTableLoading = false;
          })
          .then((res: any) => {
            this.notify.success(this.l('CopySuccessfully'));
            res.selected = false;
            res.path = this.filepath + res.path;
            this.dataList.push(res as never);
            this.refresh();
          });
      },
      /**
       * 复制代码或者链接
       * @param mp url
       * @param type 代码或者链接
       */
      copyData(mp: any, type: any, copyEel: string) {
        if (mp.indexOf('.') === -1) {
          this.notify.warn(this.l('FoldersCannotCopyLinksAndCodes'));
          return;
        }
        if (mp.path) mp = mp.path;
        this.copyText = this.getCode(mp, type);
        let clipboard = new Clipboard(copyEel);
        clipboard.on('success', () => {
          this.notify.success(this.l('CopySuccessfully'));
          clipboard.destroy();
        });
        clipboard.on('error', () => {
          this.notify.error(this.l('copyFailed'));
          clipboard.destroy();
        });
      },
      getCode(mp: any, type: string): string {
        return type === 'link' ? mp : `<img src="${mp}">`;
      },
      /**
       * 重命名
       */
      rename(item: any) {
        this.modalHelper
          .create(
            Rename,
            {
              item: item,
            },
            {
              width: '400px',
            },
          )
          .subscribe((res) => {
            if (res) {
              this.refresh();
            }
          });
      },
      /**
       * 移动文件
       */
      movefile(item: any) {
        this.modalHelper
          .create(
            MoveFile,
            {
              item: item,
            },
            {
              width: '400px',
            },
          )
          .subscribe((res) => {
            if (res) {
              this.path = [''];
              this.parentId = '';
              this.getFileUploadUrl('');
              this.refresh();
            }
          });
      },
      /**
       * 删除文件
       */
      remove(item: any) {
        this.isTableLoading = true;
        this.sysFileServiceProxy
          .delete(item ?? item.id)
          .finally(() => {
            this.isTableLoading = false;
          })
          .then(() => {
            this.refresh();
            this.notify.success(this.l('SuccessfullyDeleted'));
          });
      },
      beforupload(file: any) {
        const isJPG =
          file.type === 'image/jpeg' ||
          file.type === 'image/png' ||
          file.type === 'image/gif' ||
          file.type === 'image/bmp';
        if (!isJPG) {
          this.message.error(this.l('OnlySupportPictureFile'));
        }
        const isLtXM = file.size / 1024 / 1024 < this.maxProfilPictureBytesValue;
        if (!isLtXM) {
          this.message.error(
            this.l('ProfilePicture_Warn_SizeLimit', this.maxProfilPictureBytesValue),
          );
        }
        const isValid = isJPG && isLtXM;
        return isValid;
      },
    },
  });
</script>

<style scoped lang="less">
  :deep(.ant-upload-list-text) {
    display: none;
  }

  .bars-btn {
    margin-left: 0;
  }

  // 横向展示
  .big-list-item {
    margin-top: 20px;
    justify-content: space-evenly;

    .iconfont {
      display: block;
      font-size: 40px;
      margin: 16px 0;
      text-align: center;
    }

    :deep(.ant-row) {
      width: 100%;
      margin-left: 0 !important;
      margin-right: 0 !important;
    }

    .ant-col-sm-3 {
      box-sizing: border-box;
      padding: 15px;
      height: 150px;
      border: 1px solid rgba(0, 0, 0, 0.1);
      position: relative;
      cursor: pointer;

      &:hover {
        border: 1px solid rgba(0, 0, 0, 0.3);

        .dd-btn {
          display: block;
        }
      }

      .dd-btn {
        height: 24px;
        width: 24px;
        line-height: 24px;
        border-radius: 50%;
        color: #bfbfbf;
        background-color: #f5f5f5;
        text-align: center;
        cursor: pointer;
        position: absolute;
        margin: auto;
        right: 10px;
        top: 10px;
        display: none;
      }
    }

    .file_item__name {
      color: #4e5155;
      height: 28px;
      text-align: center;
      line-height: 28px;
      padding: 0 8px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .file_item__pixel {
      text-align: center;
    }

    .file-item__img {
      background-color: transparent;
      background-position: center center;
      background-size: cover;
      display: block;
      margin: 0 auto 0.75rem;
      width: 4rem;
      height: 4rem;
      font-size: 2.5rem;
      line-height: 4rem;
    }

    .file_item__selected {
      border-color: #1890ff !important;
      background-color: #e6f7ff !important;
    }
  }

  // smalltable展示
  .small-list-item {
    margin: 20px 0;

    .file-item__img {
      display: block;
      margin: 0 8px;
      width: 32px;
      height: 32px;
      text-align: center;
      font-size: 20px;
      line-height: 32px;
      background-color: transparent;
      background-position: center center;
      background-size: cover;
      float: left;
    }

    .dd-btn {
      height: 24px;
      width: 24px;
      line-height: 24px;
      border-radius: 50%;
      color: #bfbfbf;
      background-color: transparent;
      text-align: center;
      cursor: pointer;
      float: right;

      // position: absolute;
      // margin: auto;
      // right: 10px;
      // top: 10px;
      // display: none;
      .ant-dropdown-link {
        color: transparent;
      }
    }

    :deep(.ant-table-tbody td) {
      .icon-container {
        min-height: 10px;
        width: 50px;
        float: left;

        &::before {
          content: '';
        }
      }

      &:last-child:hover {
        .dd-btn {
          background-color: #f5f5f5;
          display: block;

          .ant-dropdown-link {
            color: #bfbfbf;
          }
        }
      }
    }

    .back-item {
      cursor: pointer;
      height: 50px;
    }
  }

  .fileUpload {
    float: left;
    margin-right: 10px;
  }
</style>
